package trans.anno;
import java.io.*;
import util.gen.*;
import util.bio.annotation.*;
import java.util.*;

/**Intersects two lists of regions subtracting the first from the second.*/
public class SubtractRegions {

	private HashMap maskerCoor;

	public SubtractRegions(String[] args){
		if (args.length == 0) Misc.printExit("\nEnter a full path file name to a regions file to use in masking and a full path directory name containg files to mask.\n");
		//load regions to use in subtraction
		File masker = new File (args[0]);
		Coordinate[] masks = Coordinate.parseFile( masker, 0, 0);
		Arrays.sort(masks);
		maskerCoor = Coordinate.splitByChromosome(masks);

		//for each file to be reduced/ masked
		File dir = new File(args[1]);
		File[] toMask = IO.extractFiles(dir);
		for (int i=0; i< toMask.length; i++){
			Coordinate[] coor = Coordinate.parseFile( toMask[i], 0, 0);
			if (dir.isDirectory() == false) dir = dir.getParentFile();
			File subtracted = new File (dir, Misc.removeExtension(toMask[i].getName()) + "_Sub.bed");
			mask (coor, subtracted);
		}
	}

	public void mask (Coordinate[] coor, File toSave){		
		try {
			PrintWriter out = new PrintWriter (new FileWriter (toSave));
			Arrays.sort(coor);
			HashMap chrCoor = Coordinate.splitByChromosome(coor);
			//for each chromosome
			Iterator it = chrCoor.keySet().iterator();
			Coordinate[] mask;
			Coordinate[] forReduction;
			while (it.hasNext()){
				String chromosome = (String) it.next();
				mask = (Coordinate[])maskerCoor.get(chromosome);
				forReduction = (Coordinate[])chrCoor.get(chromosome);
				//convert to arraylist
				ArrayList forReductionAL = new ArrayList(forReduction.length);
				for (int i=0; i< forReduction.length; i++) forReductionAL.add(forReduction[i]);
				
				//for each region to be reduced
				while (forReductionAL.size() !=0){
					Coordinate region = (Coordinate) forReductionAL.remove(0);
					if (mask !=null){
						//for each masked region
						for (int j=0; j< mask.length; j++){
							Coordinate[] pair = Coordinate.subtract (region, mask[j]);
							//completely covered?
							if (pair == null) {
								region = null;
								break;
							}
							//trimmed
							else if (pair.length == 1){
								region = pair[0];
							}
							//center punched
							else {
								//add second to arraylist
								forReductionAL.add(pair[1]);
								region = pair[0];
							}
						}
					}
					if (region != null) {
						out.println(region);
						//System.out.println(region);
					}
				}
			}
			out.close();
		} catch (Exception e){
			e.printStackTrace();
		}
	}



	public static void main (String[] args){
		new SubtractRegions(args);
	}
}
